#include "SerialCommands.h"
#include <string.h>
#include <ctype.h>

void SerialCommands::begin() {
  _len = 0;
  _buf[0] = '\0';
}

void SerialCommands::poll(SensorSuite &sensors, StorageManager &storage, Dispenser &dispenser, PowerManager &power) {
  while (Serial.available() > 0) {
    char c = (char)Serial.read();
    if (c == '\n' || c == '\r') {
      if (_len > 0) {
        _buf[_len] = '\0';
        handleCommand(_buf, sensors, storage, dispenser, power);
        _len = 0;
      }
    } else if (_len < sizeof(_buf) - 1) {
      _buf[_len++] = c;
    }
  }
}

void SerialCommands::handleCommand(const char *cmdRaw, SensorSuite &sensors, StorageManager &storage,
                                    Dispenser &dispenser, PowerManager &power) {
  char cmd[32];
  uint8_t i = 0;
  for (; cmdRaw[i] != '\0' && i < sizeof(cmd) - 1; i++) cmd[i] = toupper(cmdRaw[i]);
  cmd[i] = '\0';

  if (strcmp(cmd, "HELP") == 0) {
    Serial.println(F("Commands: HELP, STATUS, CAL_SOIL_DRY, CAL_SOIL_WET, "
                      "REFILL_HOPPER, RESET_SESSION, RESET_LIFETIME"));

  } else if (strcmp(cmd, "STATUS") == 0) {
    Serial.print(F("mode=")); Serial.print(power.modeName());
    Serial.print(F(" battery_pct=")); Serial.print(sensors.batteryPct(), 1);
    Serial.print(F(" humidity=")); Serial.print(sensors.humidityPct(), 1);
    Serial.print(F(" light_pct=")); Serial.print(sensors.lightPct(), 1);
    Serial.print(F(" soil_pct=")); Serial.print(sensors.soilPct(), 1);
    Serial.print(F(" dist_cm=")); Serial.print(sensors.distanceCm(), 1);
    Serial.print(F(" suitable=")); Serial.print(sensors.isConditionSuitable());
    Serial.print(F(" session_seeds=")); Serial.print(dispenser.sessionSeedCount());
    Serial.print(F(" lifetime_seeds=")); Serial.print(storage.lifetimeSeedCount());
    Serial.print(F(" hopper_empty=")); Serial.println(dispenser.isHopperEmpty());

  } else if (strcmp(cmd, "CAL_SOIL_DRY") == 0) {
    sensors.calibrateSoilDry();
    Serial.print(F("OK: soil dry-point calibrated, raw=")); Serial.println(storage.soilDryRaw());

  } else if (strcmp(cmd, "CAL_SOIL_WET") == 0) {
    sensors.calibrateSoilWet();
    Serial.print(F("OK: soil wet-point calibrated, raw=")); Serial.println(storage.soilWetRaw());

  } else if (strcmp(cmd, "REFILL_HOPPER") == 0) {
    dispenser.refillHopper();
    Serial.println(F("OK: hopper-empty latch cleared"));

  } else if (strcmp(cmd, "RESET_SESSION") == 0) {
    dispenser.resetSessionCount();
    Serial.println(F("OK: session seed count reset"));

  } else if (strcmp(cmd, "RESET_LIFETIME") == 0) {
    storage.resetLifetimeStats();
    Serial.println(F("OK: lifetime EEPROM stats reset"));

  } else {
    Serial.print(F("Unknown command: "));
    Serial.println(cmdRaw);
  }
}
